package com.hnkywl.sts.service.sys;

import com.google.gson.Gson;
import com.hnkywl.sts.dao.base.BmDao;
import com.hnkywl.sts.dao.bg.BgWzbmDao;
import com.hnkywl.sts.dao.organ.BmfwDao;
import com.hnkywl.sts.dao.sys.*;
import com.hnkywl.sts.entity.organ.Bmfw;
import com.hnkywl.sts.entity.sys.*;
import com.hnkywl.sts.util.BaseUtils;
import net.ruixin.orm.hibernate.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.*;

/**
 * 说明：
 * 包:        com.hnkywl.sts.service.sys
 * 类描述:    物资编码服务类
 * 创建人:    ccr
 * 创建时间: 13-2-18 上午16:01
 * 修改人:    ccr
 * 修改时间: 13-2-18 上午16:01
 * 修改备注: [说明本次修改内容]
 * 版本:        [v1.0]
 */
@Service
public class WzbmService {
    private GgDao ggDao;
    private PmDao pmDao;
    private RjwzbmDao rjwzbmDao;
    private YjwzbmDao yjwzbmDao;
    private WzbmDao wzbmDao;
    private BmDao bmDao;
    private BmfwDao bmfwDao;
    private BgWzbmDao bgWzbmDao;

    //==========setter==========
    @Autowired
    public void setGgDao(GgDao ggDao) {
        this.ggDao = ggDao;
    }

    @Autowired
    public void setPmDao(PmDao pmDao) {
        this.pmDao = pmDao;
    }

    @Autowired
    public void setRjwzbmDao(RjwzbmDao rjwzbmDao) {
        this.rjwzbmDao = rjwzbmDao;
    }

    @Autowired
    public void setYjwzbmDao(YjwzbmDao yjwzbmDao) {
        this.yjwzbmDao = yjwzbmDao;
    }

    @Autowired
    public void setWzbmDao(WzbmDao wzbmDao) {
        this.wzbmDao = wzbmDao;
    }

    @Autowired
    public void setBmDao(BmDao bmDao) {
        this.bmDao = bmDao;
    }

    @Autowired
    public void setBmfwDao(BmfwDao bmfwDao) {
        this.bmfwDao = bmfwDao;
    }

    @Autowired
    public void setBgWzbmDao(BgWzbmDao bgWzbmDao) {
        this.bgWzbmDao = bgWzbmDao;
    }

    /**
     * 方法名:     getWzbmTreeJson
     * 功能描述:   生成树Json串
     * 输入参数:   <@param wzbmId level>
     * 异常:      <RuntimeException  Exception>
     * 创建人:     ccr
     * 创建日期:   13-2-20 下午15:47
     * 修改人:     ccr
     * 修改日期:   13-2-20 下午15:47
     */
    public String getWzbmTreeJson(Long id, int level) {
        String bm = level == 0 ? "yjwzbm" : (level == 1 ? "rjwzbm" : "pm");
        String sjbm = level == 1 ? "yjwzbm_id" : (level == 2 ? "rjwzbm_id" : "");
        List<Map> tree = new ArrayList<Map>();
        tree.addAll(wzbmDao.findTreeJson(id == 0 ? null : id, bm, sjbm));
        List<Map> treeJson = new ArrayList<Map>();
        for (Map m : tree) {
            Map item = new HashMap();
            item.put("id", m.get("wzbmId") + ":" + (level + 1));
            item.put("text", "(" + m.get("code") + ")" + m.get("name") + (m.get("gysmc") != null ? ("(" + m.get("gysmc") + ")") : ""));
            item.put("state", level == 2 ? "open" : "closed");
            Map attributes = new HashMap();
            attributes.put("level", "" + (level + 1));
            attributes.put("children", "true");
            attributes.put("bgCode", m.get("bgCode"));
            item.put("attributes", attributes);
            treeJson.add(item);
        }
        return new Gson().toJson(treeJson);
    }

    /**
     * 根据codeid加载物资编码树
     */
    public String getWzbmTreeJsonByCodeid(String codeid) {
        List<Map> tree = wzbmDao.findTreeJsonByCodeid(codeid);
        return new Gson().toJson(tree);
    }

    /**
     * 方法名:     getGridJson
     * 功能描述:   生成表格Json串
     * 输入参数:   @param id 物资编码id
     * level 层级
     * pageNo,pageSize分页组件
     * 异常:      <RuntimeException  Exception>
     * 创建人:     ccr
     * 创建日期:   13-2-21 上午9:25
     * 修改人:     ccr
     * 修改日期:   13-2-21 上午9:25
     */
    public String getGridJson(Long gsjgId, Long id, int level, int pageNo, int pageSize) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
        String bm = level == 0 ? "yjwzbm" : (level == 1 ? "rjwzbm" : "pm");
        String sjbm = level == 1 ? "yjwzbm_id" : (level == 2 ? "rjwzbm_id" : "");
//        if (level != 0 && level != 3 && !bmfwDao.existChildren(gsjgId, level + 1, id, bm, sjbm)) {
//            gsjgId = null;
//        }
        String wzbmGridJson = null;
        List wzbmList;
        int total = 0;
        switch (level) {
            case 0:
                Page<Yjwzbm> yjwzbmPage = yjwzbmDao.findGridJson(YgService.getCurrentYgGsId(), pageNo, pageSize);
                wzbmList = yjwzbmPage.getResult() == null ? new ArrayList() : yjwzbmPage.getResult();
                total = yjwzbmPage.getTotalCount();
                wzbmGridJson = BaseUtils.fetchCollectionToJson(wzbmList, "id", "name", "code");
                break;
            case 1:
                Page<Rjwzbm> rjwzbmPage = rjwzbmDao.findGridJson(gsjgId, id, pageNo, pageSize);
                wzbmList = rjwzbmPage.getResult() == null ? new ArrayList() : rjwzbmPage.getResult();
                total = rjwzbmPage.getTotalCount();
                wzbmGridJson = BaseUtils.fetchCollectionToJson(wzbmList, "id", "name", "code", "yjwzbm_name");
                break;
            case 2:
                Page<Pm> pmPage = pmDao.findGridJson(gsjgId, id, pageNo, pageSize);
                wzbmList = pmPage.getResult() == null ? new ArrayList() : pmPage.getResult();
                total = pmPage.getTotalCount();
                wzbmGridJson = BaseUtils.fetchCollectionToJson(wzbmList, "id", "name", "code", "remark", "rjwzbm_name");
                break;
            case 3:
                Page<Gg> ggPage = ggDao.findGridJson(id, pageNo, pageSize);
                wzbmList = ggPage.getResult() == null ? new ArrayList() : ggPage.getResult();
                total = ggPage.getTotalCount();
                wzbmGridJson = BaseUtils.fetchCollectionToJson(wzbmList, "id", "name", "code", "oldcode", "ggxh", "ggjc", "th", "cz", "dw", "sfbj", "pm_name");
                break;
        }
        return "{\"total\":" + total + ",\"rows\":[" + wzbmGridJson + "]}";
    }

    public String search(String pmName, String ggName, String code, String cz, String ggxh, Long gsId, Integer fw, int pageNo, int pageSize) {
        if (gsId == null)
            gsId = YgService.getCurrentYgGsId();
        Page<Gg> wzbmPage = new Page<Gg>();
        if (fw != null && fw.intValue() == 1) {
            wzbmPage = ggDao.search(gsId, pmName, ggName, code, cz, ggxh, pageNo, pageSize);
        } else {
            wzbmPage = ggDao.searchAll(pmName, ggName, code, cz, ggxh, pageNo, pageSize);
        }
        List wzbmList = wzbmPage.getResult() == null ? new ArrayList() : wzbmPage.getResult();
        return "{\"total\":" + wzbmPage.getTotalCount() + ",\"rows\":" + new Gson().toJson(wzbmList) + "}";
    }

    /**
     * 方法名:       getYjwzbm
     * 功能描述:     查询一级物资编码
     */
    public Yjwzbm getYjwzbm(Long id) {
        return yjwzbmDao.get(id);
    }

    /**
     * 方法名:       getRjwzbm
     * 功能描述:     查询二级物资编码
     */
    public Rjwzbm getRjwzbm(Long id) {
        return rjwzbmDao.get(id);
    }

    /**
     * 方法名:       getPm
     * 功能描述:     查询品名
     */
    public Pm getPm(Long id) {
        return pmDao.get(id);
    }

    /**
     * 方法名:       getGg
     * 功能描述:     查询规格
     */
    public Gg getGg(Long id) {
        return ggDao.get(id);
    }


    /**
     * 通过品名材质规格代码获得规格型号
     *
     * @param specCode
     * @param materialCode
     * @return
     * @parm productCode
     */
    public List<Gg> findWzbmByPmCzCode(String productCode, String specCode, String materialCode) {
        return this.ggDao.findWzbmByPmCzCode(productCode, specCode, materialCode);
    }

    /**
     * 方法名:    新增品名
     * 功能描述:      向数据库新增品名
     * 输入参数:    <@param pm 品名>
     * 异常:      <RuntimeException  Exception>
     * 创建人:     scl
     * 创建日期:   13-2-19上午11：16
     * 修改人:     hfj
     * 修改日期:   13-2-19上午11：16
     */
    @Transactional
    public void save(Pm pm) throws SQLException {
        Rjwzbm r = rjwzbmDao.get(pm.getRjwzbm().getId());
        Bm bm = bmDao.getPmwzbm(r.getCode());
        //判断名称和代码是否重复
        if (pmDao.checkName(pm.getId(), pm.getName()) && pmDao.checkCode(pm.getId(), pm.getCode())) {
            throw new RuntimeException("品名名称或代码重复！");
        }
        pm.setCode(bm.getBmz());
        pm.setDateCreated(new Date());
        pm.setRjwzbm(rjwzbmDao.get(pm.getRjwzbm().getId()));
        pmDao.save(pm);
        bmDao.save(bm);
        if (bmfwDao.existChildren(YgService.getCurrentYgGsId(), 2, r.getId(), "pm", "rjwzbm_id")) {
            Bmfw bmfw = new Bmfw();
            bmfw.setGsId(YgService.getCurrentYgGsId());
            bmfw.setType(3);
            bmfw.setWzbmId(pm.getId());
            bmfwDao.save(bmfw);
        }
    }

    /**
     * 方法名:    跟新品名
     * 功能描述:      向数据库跟新品名
     * 输入参数:    <@param pm 品名>
     * 异常:      <RuntimeException  Exception>
     * 创建人:     scl
     * 创建日期:   13-2-19上午11：16
     * 修改人:     hfj
     * 修改日期:   13-2-19上午11：16
     */
    @Transactional
    public void updatePm(Pm pm) {
        //判断名称和代码是否重复
        if (pmDao.checkName(pm.getId(), pm.getName()) && pmDao.checkCode(pm.getId(), pm.getCode())) {
            throw new RuntimeException("品名名称或代码重复！");
        }
        //temp为临时变量
        Pm temp = pmDao.get(pm.getId());
        temp.setName(pm.getName());
//        temp.setCode(pm.getCode());
        temp.setLastUpdated(new Date());
        temp.setRemark(pm.getRemark());
        temp.setRjwzbm(pm.getRjwzbm());
        pmDao.save(temp);
    }


    /**
     * 方法名:    删除品名
     * 功能描述:      向数据库删除品名
     * 输入参数:    <@param pm 品名>
     * 异常:      <RuntimeException  Exception>
     * 创建人:     scl
     * 创建日期:   13-2-19上午11：16
     * 修改人:     hfj
     * 修改日期:   13-2-19上午11：16
     */
    @Transactional
    public void deletePm(Long id) {
        Pm pm = pmDao.get(id);
        if (pm == null) {
            throw new RuntimeException("ID为" + id + "的品名不存在");
        }
        if (pmDao.existGgJy(pm.getId())) {
            throw new RuntimeException("该品名下还存在规格");
        }
        Bm bm = bmDao.findByBmz(pm.getCode());
        bm.setZt("3");
        bm.setFCSJ(new Date());
        bmDao.save(bm);
    }

    /**
     * 方法名:     saveYjwzbm()
     * 功能描述:      向数据库插入一级物资编码
     * 输入参数:    <@param yjwzbm 一级物资实例>
     * 异常:      <RuntimeException  Exception>
     * 创建人:     hfj
     * 创建日期:   13-2-19上午10:47
     * 修改人:     hfj
     * 修改日期:   13-2-19上午10:47
     */
    @Transactional
    public void saveYjwzbm(Yjwzbm yjwzbm) throws SQLException {
        Bm bm = bmDao.getYjwzbm();
        //判断名称和代码是否重复
        if (yjwzbmDao.checkName(yjwzbm.getId(), yjwzbm.getName()) || yjwzbmDao.checkCode(yjwzbm.getId(), yjwzbm.getCode())) {
            throw new RuntimeException("品名名称或代码重复！");
        }
        yjwzbm.setCode(bm.getBmz());
        yjwzbm.setDateCreated(new Date());
        yjwzbm.setLastUpdated(new Date());
        yjwzbmDao.save(yjwzbm);
        bmDao.save(bm);
        Bmfw bmfw = new Bmfw();
        bmfw.setGsId(YgService.getCurrentYgGsId());
        bmfw.setType(1);
        bmfw.setWzbmId(yjwzbm.getId());
        bmfwDao.save(bmfw);
    }

    /**
     * 方法名:     delYjwzbm()
     * 功能描述:      向数据库删除一级物资编码
     * 输入参数:    <@param box 一级物资id集合>
     * 异常:      <RuntimeException  Exception>
     * 创建人:     hfj
     * 创建日期:   13-2-19上午10:47
     * 修改人:     hfj
     * 修改日期:   13-2-19上午10:47
     */
    @Transactional
    public void deleteYjwzbm(Long id) {
        Yjwzbm yjwzbm = yjwzbmDao.get(id);
        if (yjwzbm == null) {
            throw new RuntimeException("ID为" + id + "一级物资不存在");
        }
        if (yjwzbmDao.existRjwzbmJy(yjwzbm.getId())) {
            throw new RuntimeException("该一级物资下还存在二级物资");
        }
        Bm bm = bmDao.findByBmz(yjwzbm.getCode());
        bm.setZt("3");
        bm.setFCSJ(new Date());
        bmDao.save(bm);
    }

    /**
     * 方法名:     updateYjwzbm()
     * 功能描述:      向数据库更新一级物资编码
     * 输入参数:    <@param Yjwzbm 一级物资>
     * 异常:      <RuntimeException  Exception>
     * 创建人:     hfj
     * 创建日期:   13-2-19上午10:47
     * 修改人:     hfj
     * 修改日期:   13-2-19上午10:47
     */
    @Transactional
    public void updateYjwzbm(Yjwzbm yjwzbm) {
        if (yjwzbmDao.checkName(yjwzbm.getId(), yjwzbm.getName()) && yjwzbmDao.checkCode(yjwzbm.getId(), yjwzbm.getCode())) {
            throw new RuntimeException("一级物资编码名称或代码重复！");
        }
        Yjwzbm yjwz = yjwzbmDao.get(yjwzbm.getId());
        yjwz.setName(yjwzbm.getName());
//        yjwz.setCode(yjwzbm.getCode());
        yjwz.setLastUpdated(new Date());
        yjwzbmDao.save(yjwz);
    }

    /**
     * 方法名:    新增二级物资编码
     * 功能描述:       新增二级物资编码
     * 输入参数:    <@param rjwzbm 二级物资编码>
     * 异常:      <RuntimeException  Exception>
     * 创建人:     hl
     * 创建日期:   13-2-19上午10：16
     * 修改人:     hl
     * 修改日期:   13-2-19上午10：16
     */
    @Transactional
    public void save(Rjwzbm rjwzbm) throws SQLException {
        Yjwzbm y = yjwzbmDao.get(rjwzbm.getYjwzbm().getId());
        Bm bm = bmDao.getEjwzbm(y.getCode());
        if (rjwzbmDao.checkName(rjwzbm.getId(), rjwzbm.getName()) && rjwzbmDao.checkCode(rjwzbm.getId(), rjwzbm.getCode())) {
            throw new RuntimeException("一级物资编码名称或代码重复！");
        }
        rjwzbm.setCode(bm.getBmz());
        rjwzbm.setDateCreated(new Date());
        rjwzbm.setLastUpdated(new Date());
        rjwzbmDao.save(rjwzbm);
        bmDao.save(bm);
        if (bmfwDao.existChildren(YgService.getCurrentYgGsId(), 2, y.getId(), "rjwzbm", "yjwzbm_id")) {
            Bmfw bmfw = new Bmfw();
            bmfw.setGsId(YgService.getCurrentYgGsId());
            bmfw.setType(2);
            bmfw.setWzbmId(rjwzbm.getId());
            bmfwDao.save(bmfw);
        }
    }


    /**
     * 方法名:    更新二级物资编码
     * 功能描述:      更新二级物资编码
     * 输入参数:    <@param rjwzbm 二级物资编码>
     * 异常:      <RuntimeException  Exception>
     * 创建人:    hl
     * 创建日期:   13-2-19上午11：08
     * 修改人:     hfj
     * 修改日期:   13-2-19上午11：08
     */
    @Transactional
    public void update(Rjwzbm rjwzbm) {
        if ("".equals(rjwzbm.getName())) {
            throw new RuntimeException("二级物资编码名称不能为空！");
        } else if ("".equals(rjwzbm.getCode())) {
            throw new RuntimeException("二级物资编码不能为空！");
        }
        Rjwzbm temp = rjwzbmDao.get(rjwzbm.getId());
        temp.setName(rjwzbm.getName());
//        temp.setCode(rjwzbm.getCode());
        temp.setLastUpdated(new Date());
        rjwzbmDao.save(temp);
    }

    /**
     * 方法名:    删除二级物资编码
     * 功能描述:      删除二级物资编码
     * 输入参数:    <@param rjwzbm 二级物资编码>
     * 异常:      <RuntimeException  Exception>
     * 创建人:    hl
     * 创建日期:   13-2-19下午13：08
     * 修改人:     hfj
     * 修改日期:   13-2-19下午13：08
     */
    @Transactional
    public void delete(Long id) {
        Rjwzbm rjwzbm = rjwzbmDao.get(id);
        if (rjwzbm == null) {
            throw new RuntimeException("id为" + id + "二级物资不存在");
        }
        if (rjwzbmDao.existPmJy(rjwzbm.getId())) {
            throw new RuntimeException("该二级物资下还存在品名");
        }
        Bm bm = bmDao.findByBmz(rjwzbm.getCode());
        bm.setZt("3");
        bm.setFCSJ(new Date());
        bmDao.save(bm);
    }

    /**
     * 方法名:    新增规格
     * 功能描述:      向数据库新增规格
     * 输入参数:    <@param gg 规格>
     * 异常:      <RuntimeException  Exception>
     * 创建人:     zsp
     * 创建日期:   13-2-19下午13：20
     * 修改人:     hfj
     * 修改日期:   13-2-19下午13：20
     */
    @Transactional
    public void save(Gg gg) throws SQLException {
        Pm pm = pmDao.get(gg.getPm().getId());
        Bm bm = bmDao.getGgwzbm(pm.getCode());
        if (ggDao.checkName(gg.getId(), gg.getName()) && ggDao.checkCode(gg.getId(), gg.getCode())) {
            throw new RuntimeException("物资名称或代码重复！");
        }
        if (ggDao.checkRepeatGg(gg.getName(), gg.getGgxh(), gg.getCz())) {
            throw new RuntimeException("物资名称已存在！");
        }
        gg.setCode(bm.getBmz());
        gg.setDateCreated(new Date());
        gg.setLastUpdated(gg.getDateCreated());
        ggDao.save(gg);
    }

    /**
     * 方法名:    修改规格
     * 功能描述:      在数据库修改规格
     * 输入参数:    <@param gg 规格>
     * 异常:      <RuntimeException  Exception>
     * 创建人:     zsp
     * 创建日期:   13-2-19下午14：22
     * 修改人:     hfj
     * 修改日期:   13-2-19下午14：22
     */
    @Transactional
    public void update(Gg gg) throws SQLException {
        Gg g = ggDao.get(gg.getId());
        Bm bm = bmDao.findByBmz(g.getCode());
        if (bgWzbmDao.existGg(gg.getId())) {
            bm.setZt("2");
            bm.setZXSJ(new Date());
            gg.setId(null);
            save(gg);
            bmDao.save(bm);
        } else {
            g.setGgjc(gg.getGgjc());
            g.setName(gg.getName());
            g.setGgxh(gg.getGgxh());
            g.setCz(gg.getCz());
            ggDao.save(g);
        }
    }

    /**
     * 方法名:    删除规格
     * 功能描述:      从数据库删除规格
     * 输入参数:    <@param gg 规格>
     * 异常:      <RuntimeException  Exception>
     * 创建人:     zsp
     * 创建日期:   13-2-19下午16：05
     * 修改人:     hfj
     * 修改日期:   13-2-19下午16：05
     */
    @Transactional
    public void deleteGg(Long id) {
        Gg gg = ggDao.get(id);
        if (bgWzbmDao.existGg(gg.getId())) {
            throw new RuntimeException("禁止废除！");
        }
        Bm bm = bmDao.findByBmz(gg.getCode());
        bm.setZt("3");
        bm.setFCSJ(new Date());
        bmDao.save(bm);
    }

    /**
     * 导入数据，没有增加有就更新
     *
     * @param ggList
     */
    @Transactional
    public void saveImportWz(List<Gg> ggList) throws SQLException {
        for (Gg gg : ggList) {
            Pm pm = pmDao.get(gg.getPm().getId());
            Bm bm = bmDao.getGgwzbm(pm.getCode());
            if (ggDao.checkRepeatGg(gg.getName(), gg.getGgxh(), gg.getCz())) {
                // 更新
                Gg ggTemp = this.ggDao.findGg(gg.getName(), gg.getGgxh(), gg.getCz());
                ggTemp.setCode(bm.getBmz());
                ggTemp.setDw("吨");
                this.ggDao.save(ggTemp);
            } else {
                gg.setCode(bm.getBmz());
                gg.setDateCreated(new Date());
                gg.setLastUpdated(gg.getDateCreated());
                ggDao.save(gg);
            }
        }
    }

    /**
     * 获取所有的一级物资编码
     *
     * @return
     */
    public String findAllYjwzbmCode() {
        List<Map> list = yjwzbmDao.findAllCode();
        Gson gson = new Gson();
        return gson.toJson(list);
    }

    /**
     * 查询保供物资编码
     *
     * @param code
     * @return
     */

    public String findWzbmByCode(String code) {
        String sql = "select tb.bmylz2 from t_sys_bmb  tb  where tb.bmz = ? ";
        String objCode = this.bgWzbmDao.findBySQL(sql, code).get(0).toString();
        if (null != objCode) {
            return objCode;
        }
        return null;
    }

    public boolean isYgBmfwSetted(Long ygId) {
        return ggDao.existsSQLQuery("select yg_id from t_sys_yg_bmfw where yg_id = ?", ygId);
    }

    @Transactional
    public Gg saveFree(String name, String ggxh, String cz) throws SQLException {
        Gg gg = new Gg();
        gg.setName(name);
        gg.setGgxh(ggxh);
        gg.setCz(cz);
        gg.setDw("t");
        Pm pm = pmDao.get(17546l);
        Bm bm = bmDao.getGgwzbm(pm.getCode());
        gg.setCode(bm.getBmz());
        gg.setPm(pm);
        ggDao.save(gg);
        return gg;
    }

}
